package link.jfire.jnet.common.result;

import link.jfire.baseutil.reflect.ReflectUtil;
import link.jfire.jnet.common.exception.SelfCloseException;
import link.jfire.jnet.server.server.ServerChannelInfo;
import sun.misc.Unsafe;

@SuppressWarnings("restriction")
public class ServerInternalResult extends AbstractInternalResult
{
	private static Unsafe		unsafe		= ReflectUtil.getUnsafe();
	public static final boolean	UNDONE		= false;
	public static final boolean	DONE		= true;
	public static final int		UNWRITED	= 0;
	public static final int		WRITED		= 1;
	private volatile boolean	flowState	= UNDONE;
	private volatile int		writeState	= UNWRITED;
	private static long			writeOffset	= ReflectUtil.getFieldOffset("writeState", ServerInternalResult.class);
	private ServerChannelInfo	channelInfo;
	
	public void init(Object data, ServerChannelInfo channelInfo, int index)
	{
		this.channelInfo = channelInfo;
		this.index = index;
		this.data = data;
		flowState = UNDONE;
		writeState = UNWRITED;
	}
	
	public void clear()
	{
		channelInfo = null;
		data = null;
		flowState = UNDONE;
		writeState = UNWRITED;
	}
	
	public void flowDone()
	{
		flowState = DONE;
	}
	
	public boolean tryWrite()
	{
		if (channelInfo.isTopWriteResult(this) == false || flowState == UNDONE || writeState == WRITED)
		{
			return false;
		}
		if (unsafe.compareAndSwapInt(this, writeOffset, UNWRITED, WRITED) == false)
		{
			return false;
		}
		return true;
	}
	
	public ServerChannelInfo getChannelInfo()
	{
		return channelInfo;
	}
	
	public void setChannelInfo(ServerChannelInfo channelInfo)
	{
		this.channelInfo = channelInfo;
	}
	
	@Override
	public void closeChannel()
	{
		channelInfo.close(new SelfCloseException());
	}
	
	@Override
	public void closeChannel(Throwable e)
	{
		throw new RuntimeException("不支持该方法");
	}
	
}
